package com.wzdigit.wms.wms.service.across;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.wzdigit.framework.Shift;
import com.wzdigit.wms.basic.client.response.basic.SkuResponse;
import com.wzdigit.wms.basic.client.response.basic.WarehouseResponse;
import com.wzdigit.wms.basic.domain.asn.AsnDtl;
import com.wzdigit.wms.basic.domain.asn.AsnHeader;
import com.wzdigit.wms.basic.domain.basic.Sku;
import com.wzdigit.wms.basic.domain.basic.Warehouse;
import com.wzdigit.wms.basic.domain.mapping.CodeMapping;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.domain.order.TrsnDtl;
import com.wzdigit.wms.basic.domain.order.TrsnHeader;
import com.wzdigit.wms.basic.domain.transfer.GdnDtl;
import com.wzdigit.wms.basic.domain.transfer.GdnDtlGoods;
import com.wzdigit.wms.basic.domain.transfer.GdnHeader;
import com.wzdigit.wms.basic.enums.AsnTypeEnum;
import com.wzdigit.wms.basic.enums.GdnTypeEnum;
import com.wzdigit.wms.basic.enums.TrsnNoteTypeEnum;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.enums.writeback.OtherSystemEnum;
import com.wzdigit.wms.basic.enums.writeback.TopicEnum;
import com.wzdigit.wms.common.utils.DateTimeUtil;
import com.wzdigit.wms.wms.client.web.service.common.wms2sap.ZDT_Reserve;
import com.wzdigit.wms.wms.client.web.service.wms2sap.delivery.ZDT_003_ReqRecordsHead;
import com.wzdigit.wms.wms.client.web.service.wms2sap.delivery.ZDT_003_ReqRecordsHeadItems;
import com.wzdigit.wms.wms.client.web.service.wms2sap.delivery.ZDT_003_ReqRecordsHeadItemsRSV_A;
import com.wzdigit.wms.wms.client.web.service.wms2sap.delivery.ZDT_003_ReqRecordsHeadItemsRSV_B;
import com.wzdigit.wms.wms.client.web.service.wms2sap.material.writeBack.ZDT_066_ReqRECORDS;
import com.wzdigit.wms.wms.client.web.service.wms2sap.salesreturn.ZDT_069_Req;
import com.wzdigit.wms.wms.client.web.service.wms2sap.salesreturn.ZDT_069_ReqRECORDS;
import com.wzdigit.wms.wms.client.web.service.wms2sap.transfer.ZDT_007_ReqRecordsHead;
import com.wzdigit.wms.wms.client.web.service.wms2sap.transfer.ZDT_007_ReqRecordsHeadItems;
import com.wzdigit.wms.wms.client.web.service.wms2sap.waitcheck.instorage.ZDT_064_ReqRECORDS;
import com.wzdigit.wms.common.entity.StatusCode;
import com.wzdigit.wms.wms.service.basic.SkuService;
import com.wzdigit.wms.wms.service.basic.WarehouseService;
import com.wzdigit.wms.wms.service.core.AsnManagerService;
import com.wzdigit.wms.wms.service.core.GdnManagerService;
import com.wzdigit.wms.wms.service.core.TrsnManagerService;
import com.wzdigit.wms.wms.service.mapping.CodeMappingNewService;
import com.wzdigit.wms.wms.service.mid.IfPostbackService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class CallbackService {

    @Autowired
    private AsnManagerService asnManagerService;
    @Autowired
    private GdnManagerService gdnManagerService;
    @Autowired
    private TrsnManagerService trsnManagerService;
    @Autowired
    private IfPostbackService ifPostbackService;
    @Autowired
    private WarehouseService warehouseService;
    @Autowired
    private CodeMappingNewService codeMappingNewService;
    @Autowired
    private SkuService skuService;

    private IfPostback createIfPostback() {
        return new IfPostback();
    }

    /**
     * 创建 IfPostback
     *
     * @param asnHeader
     * @return
     */
    private IfPostback createIfPostback(AsnHeader asnHeader) {
        IfPostback ifPostback = this.createIfPostback();
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        if (asnHeader.getAsnType().equals(AsnTypeEnum.R99.getCode())) {
            ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_TRANSFER.getEnumName());
        } else if (asnHeader.getAsnType().equals(AsnTypeEnum.R04.getCode())) {
            ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_DELIVERY.getEnumName());
        } else if (asnHeader.getAsnType().equals(AsnTypeEnum.R09.getCode())) {
            ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_WAIT_CHECK_IN_INSTORAGE.getEnumName());
        }
        ifPostback.setCreateTime(new Date());
//        ifPostback.setPostbackTime(new Date());
        ifPostback.setPostbackNo(asnHeader.getAsnNo());
        ifPostback.setPostbackSourceNo(asnHeader.getSourceNo());
        ifPostback.setPostbackType(asnHeader.getAsnType());
        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
        return ifPostback;
    }

    /**
     * 创建 IfPostback
     *
     * @param gdnHeader
     * @return
     */
//    private IfPostback createIfPostback(GdnHeader gdnHeader) {
    private IfPostback createIfPostback(GdnHeader gdnHeader,String noteNo) {
        IfPostback ifPostback = this.createIfPostback();
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        if (gdnHeader.getGdnType().equals(GdnTypeEnum.D99.getCode())) {
            ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_TRANSFER.getEnumName());
        } else if (gdnHeader.getGdnType().equals(GdnTypeEnum.D10.getCode())) {
            ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_SALES_RETURN.getEnumName());
        } else if (gdnHeader.getGdnType().equals(GdnTypeEnum.D03.getCode())) {
            ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_MATERIAL_WRITE_BACK.getEnumName());
        }
        ifPostback.setCreateTime(new Date());
        ifPostback.setPostbackTime(new Date());

        ifPostback.setPostbackSourceNo(gdnHeader.getSourceShipNotice());
        ifPostback.setPostbackType(gdnHeader.getGdnType());
        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());

        if (noteNo == null) {
            ifPostback.setPostbackNo(gdnHeader.getGdnNo());
        }else {
            String postbackNo = gdnHeader.getGdnNo() +"$" +noteNo;
            ifPostback.setPostbackNo(postbackNo);
        }
        return ifPostback;
    }


    private ZDT_Reserve createZdtReserve() {
        ZDT_Reserve reserve = new ZDT_Reserve();
        reserve.setRsv1("");
        reserve.setRsv2("");
        reserve.setRsv3("");
        reserve.setRsv4("");
        reserve.setRsv5("");
        return reserve;
    }

    private String getWhsCode(Integer whsId) {
        WarehouseResponse warehouse = this.warehouseService.getWarehouse(whsId);
        return warehouse == null ? null : warehouse.getWhsCode();
    }

    /**
     * 回传
     *
     * @param gdnHeader
     */
    public void Callback(GdnHeader gdnHeader) {
        try {
            IfPostback ifPostback = this.createIfPostback(gdnHeader,null);

            //公司间退货
            if (gdnHeader.getGdnType().equals(GdnTypeEnum.D10.getCode())) {
                if (gdnHeader.getFactory().equals("5500") || gdnHeader.getFactory().equals("5520")) {
                    ifPostback.setPostbackContent(this.create_D10_JSON(gdnHeader));
                }
            } else if (gdnHeader.getGdnType().equals(GdnTypeEnum.D99.getCode())) {
            	//其他出库
                ifPostback.setPostbackContent(this.create_D99_JSON(gdnHeader));
            } else {
            	//其他直接返回
                return;
            }
            ifPostback.setCreateTime(new Date());
            this.ifPostbackService.addOne(ifPostback);
        } catch (Exception ex) {
            Shift.fatal("写SAP回传信息失败!");
        }
    }

    /**
     * 回传  多次回传使用
     *
     * @param trsnHeader
     */
    public void Callback(TrsnHeader trsnHeader) {
        if (trsnHeader.getNoteType().equals(TrsnNoteTypeEnum.OUT_STORAGE.getEnumName())) {
            GdnHeader gdnHeader = this.gdnManagerService.selectByNo(trsnHeader.getFmDoc());
            //返包出库
            this.Callback(gdnHeader, trsnHeader);
        } else if (trsnHeader.getNoteType().equals(TrsnNoteTypeEnum.IN_STORAGE.getEnumName())) {
            AsnHeader asnHeader = this.asnManagerService.getAsnHeaderService().selectByNo(trsnHeader.getFmDoc());
        }
    }

    /**
     * 回传  多次回传使用
     *
     * @param gdnHeader
     * @param trsnHeader
     */
    public void Callback(GdnHeader gdnHeader, TrsnHeader trsnHeader) {
        try {
            String noteNo = trsnHeader.getNoteNo();


//            IfPostback ifPostback = this.createIfPostback(gdnHeader);
            IfPostback ifPostback = this.createIfPostback(gdnHeader,noteNo);
            //返包出库
            if (gdnHeader.getGdnType().equals(GdnTypeEnum.D03.getCode())) {
                ifPostback.setPostbackContent(this.create_D03_JSON(gdnHeader, trsnHeader));
            } else {
            	//其他直接返回
                return;
            }
            ifPostback.setCreateTime(new Date());
            this.ifPostbackService.addOne(ifPostback);
        } catch (Exception ex) {
            Shift.fatal("写SAP回传信息失败!");
        }
    }

    /**
     * 回传
     *
     * @param asnHeader
     */
    public void Callback(AsnHeader asnHeader) {
        try {
            IfPostback ifPostback = this.createIfPostback(asnHeader);
            //销售退货
            if (asnHeader.getAsnType().equals(AsnTypeEnum.R04.getCode())) {
                ifPostback.setPostbackContent(this.create_R04_JSON(asnHeader));
            }
            //单据类型是“公司间发货入库(R09)”，在点“关单”按钮或自动关单
            else if (asnHeader.getAsnType().equals(AsnTypeEnum.R09.getCode())) {
                if (asnHeader.getFactory().equals("5500") || asnHeader.getFactory().equals("5520")) {
                    ifPostback.setPostbackContent(this.create_R09_JSON(asnHeader));
                }
            } else if (asnHeader.getAsnType().equals(AsnTypeEnum.R99.getCode())) {
            	//其它入库
                ifPostback.setPostbackContent(this.create_R99_JSON(asnHeader));
            } else {
            	//其他直接返回
                return;
            }
            ifPostback.setCreateTime(new Date());
            this.ifPostbackService.addOne(ifPostback);
        } catch (Exception ex) {
            Shift.fatal("写SAP回传信息失败!");
        }
    }

    /**
     * 销售退货(R04) 交货单接口(DeliveryService)
     *
     * @param asnHeader
     * @throws Exception
     */
    public String create_R04_JSON(AsnHeader asnHeader) throws Exception {

        ZDT_003_ReqRecordsHead zdt_003_reqRecordsHead = new ZDT_003_ReqRecordsHead();
        zdt_003_reqRecordsHead.setZWJHD(asnHeader.getAsnNo() == null ? "" : asnHeader.getAsnNo()); //单号
        zdt_003_reqRecordsHead.setVSTEL(""); //传空
        zdt_003_reqRecordsHead.setWADAT_IST(asnHeader.getAsnApprovedTime() == null ? "" : asnHeader.getAsnApprovedTime().toString()); //审核日期/生效日期;
        ZDT_Reserve reserve = this.createZdtReserve();
        reserve.setRsv1("X");
        zdt_003_reqRecordsHead.setRSV(reserve);

        List<ZDT_003_ReqRecordsHeadItems> items = new ArrayList<>();

        String whsCode = this.getWhsCode(asnHeader.getToWhs());

        List<AsnDtl> asnDtlList = this.asnManagerService.getAsnDtlService().selectListByAsnNo(asnHeader.getAsnNo());
        for (AsnDtl asnDtl : asnDtlList) {
            ZDT_003_ReqRecordsHeadItems item = new ZDT_003_ReqRecordsHeadItems();
            item.setZWFHH(asnDtl.getAsnLineNo() == null ? "" : asnDtl.getAsnLineNo());  //行号
            item.setLFIMG(asnDtl.getRcvQty() == null ? "" : asnDtl.getRcvQty().toString());  //数量

            item.setLGORT("");  //库存地点
            if (asnHeader.getFactory() != null && whsCode != null) {
                CodeMapping codeMapping = codeMappingNewService.selectByWhsCodeAndFactory(asnHeader.getFactory(), whsCode, asnDtl.getQaStatus());
                if (codeMapping != null) {
                    item.setLGORT(codeMapping.getMappingCode());  //库存地点
                }
            }
            SkuResponse sku = this.skuService.getSku(asnDtl.getSkuId());
            item.setMATNR(sku.getSkuCode());  //物料编码
            item.setVGBEL(asnDtl.getSoNo() == null ? "" : asnDtl.getSoNo());  //销售单号
            item.setVGPOS(asnDtl.getSoLineNo() == null ? "" : asnDtl.getSoLineNo());  //销售行号
            item.setPIKMG(asnDtl.getRcvQty() == null ? "" : asnDtl.getRcvQty().toString());  //数量
            ZDT_Reserve rsv = new ZDT_Reserve();
            rsv.setRsv1("X");
            rsv.setRsv3(asnHeader.getSourceNo()==null?"":asnHeader.getSourceNo());//设置来源单号
            rsv.setRsv4(asnDtl.getSourceLineNo()==null?"":asnDtl.getSourceLineNo());//设置来源单行号

            item.setRSV(rsv);
            item.setRSV_A(new ZDT_003_ReqRecordsHeadItemsRSV_A());
            item.setRSV_B(new ZDT_003_ReqRecordsHeadItemsRSV_B());

            items.add(item);
        }
        zdt_003_reqRecordsHead.setItems(items.toArray(new ZDT_003_ReqRecordsHeadItems[0]));

        ArrayList<ZDT_003_ReqRecordsHead> list = new ArrayList<>();
        list.add(zdt_003_reqRecordsHead);
        return JSON.toJSONString(list);
    }

    /**
     * 公司间发货入库(R09) 待检入库接口
     *
     * @param asnHeader
     */
    public String create_R09_JSON(AsnHeader asnHeader) throws Exception {

//        ZDT_064_Req head = new ZDT_064_Req();

        List<ZDT_064_ReqRECORDS> items = new ArrayList<>();

        List<AsnDtl> asnDtlList = this.asnManagerService.getAsnDtlService().selectListByAsnNo(asnHeader.getAsnNo());
        Map<Integer, CodeMapping> map = new HashMap<>();
        for (AsnDtl asnDtl : asnDtlList) {
            if (!map.containsKey(asnDtl.getWhsId())) {
                //根据WMS的仓库CODE+factory找SAP的仓库CODE
                String toWhsCode = this.getWhsCode(asnDtl.getWhsId());
                CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(asnHeader.getFactory(), toWhsCode, asnDtl.getQaStatus());
                if (toCodeMapping == null) {
                    String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, asnHeader.getFactory());
                    Shift.fatal(StatusCode.BUSINESS_ERR, message);
                }
                map.put(asnDtl.getWhsId(), toCodeMapping);
            }
            ZDT_064_ReqRECORDS headItem = new ZDT_064_ReqRECORDS();
            headItem.setWMSID(asnDtlList.get(0).getAsnDtlId().toString());  //外围系统ID

//            headItem.setBILLTYPE("D");  //单据类型   1 送货单 2 采购单 3 交货单 4 成品收货
            //上面是原来的
            headItem.setBILLTYPE("4");  //单据类型   1 送货单 2 采购单 3 交货单 4 成品收货

            headItem.setSTREAMNO(asnHeader.getAsnNo());   //送货单号
            headItem.setSTREAMITEM(asnDtl.getAsnLineNo());  //送货单行号

            headItem.setVBELN(asnHeader.getSourceNo());   //送货单号
            headItem.setPOSNR(asnDtl.getSourceLineNo());  //送货单行号

            headItem.setBUDAT(DateTimeUtil.getDateStr());  //过帐日期

            SkuResponse sku = skuService.getSku(asnDtl.getSkuId());
            headItem.setMATNR(sku.getSkuCode()); //物料编码
            headItem.setMENGE(asnDtl.getRcvQty().toString());   //采购订单数量（交货数量）
            headItem.setLGORT(map.get(asnDtl.getWhsId()).getMappingCode());//库位（转入）/SAP说传他们的仓库
            headItem.setRSV1(this.createZdtReserve());
            headItem.setRSV2(this.createZdtReserve());

            items.add(headItem);
        }
//        head.setRECORDS(items.toArray(new ZDT_064_ReqRECORDS[0]));
//        List<ZDT_064_Req> reqList =new ArrayList<>();
//        reqList.add(head);

//        return JSON.toJSONString(head);
//        return JSON.toJSONString(head, SerializerFeature.WriteClassName);
        return JSON.toJSONString(items, SerializerFeature.WriteClassName);
    }

    /**
     * 其它入库(R99) 调拨接口
     *
     * @param asnHeader
     * @throws Exception
     */
    public String create_R99_JSON(AsnHeader asnHeader) throws Exception {
        List<ZDT_007_ReqRecordsHead> heads = new ArrayList<>();
        ZDT_007_ReqRecordsHead head = new ZDT_007_ReqRecordsHead();

        if (asnHeader.getAsnType().equals(AsnTypeEnum.R99.getCode())) {
            //其他入库
            head.setZCJLX("8");
            head.setBWART("Y10");
        }

        head.setZGLJYD(asnHeader.getAsnNo());   //单号
        head.setEKORG("");//采购组织（创建类型2必填）
        head.setBUKRS("");//公司代码（创建类型2必填）
        head.setLIFNR(asnHeader.getVendorId() == null ? "" : asnHeader.getVendorId().toString());//供应商 （创建类型2必填）
        head.setZCJR(asnHeader.getModifyUser());
        head.setZCJRZH(asnHeader.getModifyUser());//创建人账号

        head.setZCJRQ(DateTimeUtil.getDateStr());//创建日期
        head.setZCJSJ(DateTimeUtil.getTimeStr());//创建时间
        ZDT_Reserve zr = this.createZdtReserve();


        //ITEMS
        List<ZDT_007_ReqRecordsHeadItems> items = new ArrayList<>();
        List<AsnDtl> asnDtlList = this.asnManagerService.getAsnDtlService().selectListByAsnNo(asnHeader.getAsnNo());
        if(asnDtlList!=null&&asnDtlList.size()!=0){
            zr.setRsv2(asnDtlList.get(0).getReserveNo()==null?"":asnDtlList.get(0).getReserveNo());//这个字段其实应该放表头,随便取一条
        }

        head.setRSV(zr);
        for (AsnDtl asnDtl : asnDtlList) {
            String toFactory = asnHeader.getFactory();
            //根据WMS的仓库CODE+factory找SAP的仓库CODE
            String toWhsCode = this.getWhsCode(asnDtl.getWhsId());
            CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(toFactory, toWhsCode, asnDtl.getQaStatus());
            if (toCodeMapping == null) {
                String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, toFactory);
                Shift.fatal(StatusCode.BUSINESS_ERR, message);
            }
            //
            ZDT_007_ReqRecordsHeadItems headItems = new ZDT_007_ReqRecordsHeadItems();

            headItems.setZCGHH(String.valueOf(asnDtl.getAsnLineNo()));//调拨单行号

            //特殊库存 的意思 就是库存是绑定订单的,转出转入都绑定,所以是两个e from SAP——WZP
            headItems.setSOBKZ("E");//特殊库存标识（转出）
            headItems.setUMSOK("E");//特殊库存标识（转入）

            headItems.setKDAUF(asnDtl.getSoNo());//订单号码（转出）
            headItems.setKDPOS(asnDtl.getSoLineNo());//订单行项目（转出）

            headItems.setMAT_KDAUF("");//订单号码（转入）
            headItems.setMAT_KDPOS("");//订单行项目（转入）

            headItems.setWERKS("");//工厂（转出）
            headItems.setUMLGO("");//库位（转出）/SAP说传他们的仓库

            headItems.setUMWRK(toFactory);//工厂（转入）
            headItems.setLGORT(toCodeMapping.getMappingCode());//库位（转入）/SAP说传他们的仓库

            Sku sku = skuService.getSkuByPk(asnDtl.getSkuId());
            headItems.setMATNR(sku.getSkuCode());//物料号

            headItems.setMENGE(asnDtl.getRcvQty().toString());//数量

            headItems.setBUDAT(DateTimeUtil.getDateStr());//过帐日期
            ZDT_Reserve reserve = this.createZdtReserve();
            reserve.setRsv1(asnDtl.getCostCenter());
            headItems.setRSV(reserve);

            items.add(headItems);
        }

        ZDT_007_ReqRecordsHeadItems[] recordsHeadItemsArr = items.toArray(new ZDT_007_ReqRecordsHeadItems[0]);

        head.setItems(recordsHeadItemsArr);
        heads.add(head);
//        return JSON.toJSONString(head);
        return JSON.toJSONString(heads, SerializerFeature.WriteClassName);
    }

    /**
     * 反包出库(D03)  领料单接口
     *
     * @param gdnHeader
     * @param trsnHeader
     */
    public String create_D03_JSON(GdnHeader gdnHeader, TrsnHeader trsnHeader) throws Exception {

//        ZDT_066_Req head = new ZDT_066_Req();
        List<ZDT_066_ReqRECORDS> items = new ArrayList<>();

        List<GdnDtl> gdnDtls = this.gdnManagerService.selectDetailsByHeaderId(gdnHeader.getGdnHeaderId());
        List<TrsnDtl> trsnDtlList = this.trsnManagerService.selectDetailsByTrsnId(trsnHeader.getTrsnHeaderId());

        Map<Integer, CodeMapping> whsMap = new HashMap<>();

        for (TrsnDtl trsnDtl : trsnDtlList) {
            GdnDtl gdnDtl = gdnDtls.stream().filter(t -> trsnDtl.getFmDocLine().equals(t.getGdnLineNo().toString())).findFirst().orElse(null);
            if (!whsMap.containsKey(gdnDtl.getWhsId())) {
                //根据WMS的仓库CODE+factory找SAP的仓库CODE
                String toWhsCode = this.getWhsCode(gdnDtl.getWhsId());
                CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(gdnHeader.getFactory(), toWhsCode, gdnDtl.getQaStatus());
                if (toCodeMapping == null) {
                    String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, gdnHeader.getFactory());
                    Shift.fatal(StatusCode.BUSINESS_ERR, message);
                }
                whsMap.put(gdnDtl.getWhsId(), toCodeMapping);
            }
            ZDT_066_ReqRECORDS headItem = new ZDT_066_ReqRECORDS();
            headItem.setZPCKNO(gdnHeader.getSourceShipNotice());//领退料单号

//            headItem.setGUID(gdnDtl.getSourceShipNoticeItem().toString());//对象 GUID（领料单行号）
            headItem.setGUID(gdnDtl.getGdnRef5());//对象 GUID（领料单行号）

//            headItem.setZTYPE("D");//单据类型   1 送货单 2 采购单 3 交货单 4 成品收货
            headItem.setZTYPE("D");//生产领料，上面是原来的
//            headItem.setZFLAG("0");//回写状态
            headItem.setZFLAG("1");//回写状态
            headItem.setENMNG(trsnDtl.getQty().toString());//发货数量
            headItem.setAUDITUSER(trsnDtl.getCreateUser());//审核人
            headItem.setAUDITTIME(DateTimeUtil.getDateStr());  //审核时间

            headItem.setRSV1(whsMap.get(gdnDtl.getWhsId()).getWmsCode());//预留字段1

            headItem.setRSV1(gdnDtl.getSoNo());//预留字段1
            headItem.setRSV2(gdnDtl.getSoLineNo());//预留字段2

            if (gdnDtl.getGdnRef1()== null) {
                //合格标识
                headItem.setRSV3("");//预留字段3
            }else {
                headItem.setRSV3(gdnHeader.getGdnRef1());//预留字段3
            }

            if (gdnDtl.getGdnRef2() == null) {
                //发料单属性
                headItem.setRSV4("");//预留字段4
            }else {
                headItem.setRSV4(gdnHeader.getGdnRef2());//预留字段4
            }

            headItem.setRSV5("");       //预留字段5
            headItem.setRSV6("");       //预留字段6
            headItem.setRSV7("");       //预留字段7
            headItem.setRSV8("");       //预留字段8
            headItem.setRSV9("");       //预留字段9
            headItem.setRSV10("");      //预留字段10
            items.add(headItem);
        }
//        head.setRECORDS(items.toArray(new ZDT_066_ReqRECORDS[0]));
//        List<ZDT_066_Req> headList =new ArrayList<>();
//        headList.add(head);

//        return JSON.toJSONString(head);
        return JSON.toJSONString(items, SerializerFeature.WriteClassName);
    }

    /**
     * 公司间退货出库(D10) 公司间退货单接口
     *
     * @param gdnHeader
     */
    public String create_D10_JSON(GdnHeader gdnHeader) throws Exception {
        ZDT_069_Req head = new ZDT_069_Req();
        List<ZDT_069_ReqRECORDS> items = new ArrayList<>();

        List<GdnDtl> gdnDtlList = this.gdnManagerService.selectDetailsByHeaderId(gdnHeader.getGdnHeaderId());
        Map<Integer, CodeMapping> whsMap = new HashMap<>();
        for (GdnDtl gdnDtl : gdnDtlList) {
            if (!whsMap.containsKey(gdnDtl.getWhsId())) {
                //根据WMS的仓库CODE+factory找SAP的仓库CODE
                String toWhsCode = this.getWhsCode(gdnDtl.getWhsId());
                CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(gdnHeader.getFactory(), toWhsCode, gdnDtl.getQaStatus());
                if (toCodeMapping == null) {
                    String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, gdnHeader.getFactory());
                    Shift.fatal(StatusCode.BUSINESS_ERR, message);
                }
                whsMap.put(gdnDtl.getWhsId(), toCodeMapping);
            }
            ZDT_069_ReqRECORDS headItem = new ZDT_069_ReqRECORDS();
            headItem.setDOCTP("ZC24");
            headItem.setEBELN(gdnHeader.getSourceShipNotice());
            headItem.setEBELP(gdnDtl.getSourceShipNoticeItem().toString());
            SkuResponse sku = skuService.getSku(gdnDtl.getSkuId());
            headItem.setMATNR(sku.getSkuCode());
            headItem.setMENGE(gdnDtl.getShipQty().toString());
            headItem.setLGORT(whsMap.get(gdnDtl.getWhsId()).getMappingCode());
            headItem.setERNAM(gdnHeader.getModifyUser());
            headItem.setBUDAT(DateTimeUtil.getDateStr());
            items.add(headItem);
        }
        head.setRECORDS(items.toArray(new ZDT_069_ReqRECORDS[0]));
//        return JSON.toJSONString(head);
        return JSON.toJSONString(head, SerializerFeature.WriteClassName);
    }

    /**
     * 其他出库(D99)  调拨接口
     *
     * @param gdnHeader
     * @throws Exception
     */
    public String create_D99_JSON(GdnHeader gdnHeader) throws Exception {

        List<ZDT_007_ReqRecordsHead> headList = new ArrayList<>();

        ZDT_007_ReqRecordsHead head = new ZDT_007_ReqRecordsHead();
        if (gdnHeader.getGdnType().equals(GdnTypeEnum.D99.getCode())) {
            //其他出库
            head.setZCJLX("8");
            head.setBWART("Y09");
        }
        head.setZGLJYD(gdnHeader.getGdnNo());   //单号
        head.setEKORG("");//采购组织（创建类型2必填）
        head.setBUKRS("");//公司代码（创建类型2必填）
        head.setLIFNR("");//供应商 （创建类型2必填）
        head.setZCJR(gdnHeader.getModifyUser());
        head.setZCJRZH(gdnHeader.getGdnCreateUser());//创建人账号

        head.setZCJRQ(DateTimeUtil.getDateStr());//创建日期
        head.setZCJSJ(DateTimeUtil.getTimeStr());//创建时间

        ZDT_Reserve zdtReserve1 = this.createZdtReserve();
        List<GdnDtl> gdnDtlList = this.gdnManagerService.selectDetailsByHeaderId(gdnHeader.getGdnHeaderId());
        if(gdnDtlList!=null&&gdnDtlList.size()!=0){
            zdtReserve1.setRsv2(gdnDtlList.get(0).getReserveNo()==null?"":gdnDtlList.get(0).getReserveNo());
        }
       /* if (gdnHeader.getCtnrShipNo() == null) {
            zdtReserve1.setRsv2("");//中间表A3
        }else {
            zdtReserve1.setRsv2(gdnHeader.getCtnrShipNo());//中间表A3
        }*/

        head.setRSV(zdtReserve1);

        //ITEMS
        List<ZDT_007_ReqRecordsHeadItems> items = new ArrayList<>();

        Map<Integer, String> skuMap = new HashMap<>();
        for (GdnDtl gdnDtl : gdnDtlList) {
            String fmFactory = gdnHeader.getFactory();
            Warehouse fmWarehouse = this.warehouseService.selectByPK(gdnDtl.getWhsId());
            //根据WMS的仓库CODE+factory找SAP的仓库CODE
            String fmWhsCode = fmWarehouse.getWhsCode();
            CodeMapping fmCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, gdnDtl.getQaStatus());
            if (fmCodeMapping == null) {
                String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", fmWhsCode, fmFactory);
                Shift.fatal(StatusCode.BUSINESS_ERR, message);
            }

            List<GdnDtlGoods> gdnDtlGoodsList = this.gdnManagerService.selectGoodsByDtlId(gdnDtl.getGdnDtlId());

            BigDecimal qty = gdnDtlGoodsList.stream().map(GdnDtlGoods::getQty).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

            ///
            ZDT_007_ReqRecordsHeadItems headItems = new ZDT_007_ReqRecordsHeadItems();

            headItems.setZCGHH(String.valueOf(gdnDtl.getGdnLineNo()));//调拨单行号

            //特殊库存 的意思 就是库存是绑定订单的,转出转入都绑定,所以是两个e from SAP——WZP
            headItems.setSOBKZ("E");//特殊库存标识（转出）
            headItems.setUMSOK("E");//特殊库存标识（转入）

            headItems.setKDAUF(gdnDtl.getSoNo());//订单号码（转出）
            headItems.setKDPOS(gdnDtl.getSoLineNo());//订单行项目（转出）

            headItems.setMAT_KDAUF("");//订单号码（转入）
            headItems.setMAT_KDPOS("");//订单行项目（转入）

            headItems.setWERKS(fmFactory);//工厂（转出）
            headItems.setUMLGO(fmCodeMapping.getMappingCode());//库位（转出）/SAP说传他们的仓库

            headItems.setUMWRK("");//工厂（转入）
            headItems.setLGORT("");//库位（转入）/SAP说传他们的仓库

            if (!skuMap.containsKey(gdnDtl.getSkuId())) {
                Sku sku = skuService.getSkuByPk(gdnDtl.getSkuId());
                skuMap.put(sku.getSkuId(), sku.getSkuCode());
            }

            headItems.setMATNR(skuMap.get(gdnDtl.getSkuId()));//物料号

            headItems.setMENGE(qty.toString());//数量

            headItems.setBUDAT(DateTimeUtil.getDateStr());//过帐日期

            ZDT_Reserve zdtReserve = this.createZdtReserve();
            zdtReserve.setRsv1(gdnDtl.getCostCenter());//成本中心(创建类型8必填)
            //TODO 下面四个说暂时没值
//            zdtReserve.setRsv2();//Rsv2内需单号
//            zdtReserve.setRsv3();//Rsv3内需单行项目
//            zdtReserve.setRsv4();//Rsv4总账科目
//            zdtReserve.setRsv5();//Rsv5转入物料


            headItems.setRSV(zdtReserve);

            items.add(headItems);
        }

        head.setItems(items.toArray(new ZDT_007_ReqRecordsHeadItems[0]));

//        return JSON.toJSONString(head);
        headList.add(head);
        return JSON.toJSONString(headList, SerializerFeature.WriteClassName);
    }

}
